import { NextResponse } from 'next/server';
import { PrismaClient } from '@prisma/client';
import * as crypto from 'crypto';
import * as jwt from 'jsonwebtoken';

const prisma = new PrismaClient();

// 安全的密码比较函数（防止时序攻击）
function safeCompare(a: string, b: string): boolean {
  // 确保两个字符串长度相同以防止时序攻击
  const buffA = Buffer.from(a);
  const buffB = Buffer.from(b);
  
  try {
    return crypto.timingSafeEqual(buffA, buffB);
  } catch (e) {
    // 如果长度不同，会抛出错误
    return false;
  }
}

// 验证密码
function verifyPassword(password: string, hash: string | null, salt: string | null): boolean {
  if (!hash || !salt) return false;
  
  try {
    // 使用相同的方法哈希输入的密码
    const hashedPassword = crypto.pbkdf2Sync(
      password,
      salt,
      10000, // 迭代次数
      64,    // 密钥长度
      'sha512'
    ).toString('hex');
    
    // 安全比较两个哈希
    return safeCompare(hashedPassword, hash);
  } catch (error) {
    console.error('密码验证错误:', error);
    return false;
  }
}

// 创建JWT令牌
function createToken(
  userId: number, 
  username: string, 
  isAdmin: boolean, 
  permissions: any[]
): string {
  const secret = process.env.JWT_SECRET || 'your-secret-key';
  
  return jwt.sign(
    { userId, username, isAdmin, permissions },
    secret,
    { expiresIn: '12h' }
  );
}

export async function POST(request: Request) {
  try {
    const body = await request.json();
    const { username, password } = body;
    
    // 输入验证
    if (!username || !password) {
      return NextResponse.json(
        { message: '用户名和密码不能为空' },
        { status: 400 }
      );
    }
    
    // 查找用户 - 由于类型问题，暂时使用any类型
    const user = await prisma.$queryRaw`
      SELECT p.*, json_group_array(perm.permissionType) as permissionTypes
      FROM Player p 
      LEFT JOIN Permission perm ON p.id = perm.playerId
      WHERE p.name = ${username} AND p.isAdmin = 1
      GROUP BY p.id
    ` as any[];
    
    // 用户不存在或不是管理员
    if (!user || user.length === 0) {
      return NextResponse.json(
        { message: '用户名或密码错误' },
        { status: 401 }
      );
    }
    
    const userData = user[0];
    
    // 验证密码
    let isCorrectPassword = false;
    
    // 如果用户有密码哈希和盐值，则使用安全验证
    if (userData.passwordHash && userData.passwordSalt) {
      isCorrectPassword = verifyPassword(password, userData.passwordHash, userData.passwordSalt);
    } else {
      // 兼容模式: 对于未设置密码哈希的账户，使用默认的硬编码密码
      // 在实际环境中应该移除此处理方式
      isCorrectPassword = password === 'wdnajsnd12u8921jip[p[]p[]';
      
      // 如果验证成功，自动生成密码哈希和盐值
      if (isCorrectPassword) {
        const salt = crypto.randomBytes(16).toString('hex');
        const hash = crypto.pbkdf2Sync(
          password,
          salt,
          10000,
          64,
          'sha512'
        ).toString('hex');
        
        // 使用原始SQL更新密码信息
        await prisma.$executeRaw`
          UPDATE Player 
          SET passwordHash = ${hash}, passwordSalt = ${salt}
          WHERE id = ${userData.id}
        `;
      }
    }
    
    if (!isCorrectPassword) {
      return NextResponse.json(
        { message: '用户名或密码错误' },
        { status: 401 }
      );
    }
    
    // 解析权限数据
    let permissions = [];
    try {
      if (userData.permissionTypes) {
        permissions = JSON.parse(userData.permissionTypes);
      }
    } catch (e) {
      console.error('解析权限数据错误:', e);
    }
    
    // 生成JWT令牌
    const token = createToken(
      userData.id,
      userData.name,
      userData.isAdmin === 1,
      permissions
    );
    
    // 返回用户信息与令牌
    return NextResponse.json({
      token,
      username: userData.name,
      userId: userData.id,
      permissions: permissions
    });
    
  } catch (error) {
    console.error('登录错误:', error);
    return NextResponse.json(
      { message: '登录过程中发生错误' },
      { status: 500 }
    );
  }
} 